/*
   webpack的配置文件
   作用：指示webpack加载相应的配置
   所有的构建工具基于nodejs运行  模块化默认采用comminjs
*/

/*
  HMR:热模块替换/模块热替换
  作用：一个模块发生变化，只会重新打包这个模块（而不是打包所有）
  极大提升构建速度

  样式文件：可以使用HMR功能：因为style-loader 内部实现了
  js文件：默认不能使用HMR功能
  html文件：默认不能使用HMR功能，同时会导致问题：html文件不能热更新了~   （不用做HMR功能）
  解决：修改entry入口将html文件引入
*/

/*
   source-map:一种提供源代码到构建后代码的映射技术（如果构建后代码出错了，通过映射关系可以追踪到源代码错误）
   [inline-|hidden-|eval-]source-map   inline- eval- 内联 开发环境  速度更快  hidden- nosources- cheap- 外联  生产模式
   [nosources-]source-map  
   [cheap-[module-]]source-map 
*/

/*
  PWA：渐进式网络开发应用程序（离线可访问）

*/

//resolve 方法处理绝对路径
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin=require('mini-css-extract-plugin');  //打包css资源
const {resolve,join}=require('path');
const OptimizeCssAssetsWebpackPlugin=require('optimize-css-assets-webpack-plugin');// 压缩css代码
/*
  tree shaking
  去掉无用的代码
  前提：1.必须使用es6模块化 2.开启production环境

*/ 
const glob=require('glob');
const PATHS={src:join(__dirname,'src')}
const PurgecssWebpackPlugin=require('purgecss-webpack-plugin')


//开发环境  设置node环境变量 决定package.json  browserslist的配置
//process.env.NODE_ENV="development";

//复用loader
const commonCssLoader=[
    //创建style标签
    //'style-loader',
    MiniCssExtractPlugin.loader,
    //css样式
    'css-loader',
    /*css兼容处理：postcss-->postcss-loader postcss-preset-env*/
    'postcss-loader',
]

module.exports={
    //webpack配置
    //入口
    entry:['./src/js/index.js'],
    //输出
    output:{
        filename:'js/[name].js',
        //__dirname 目录的绝对路径
        path:resolve(__dirname,'build'),
        //所有资源引入公共路径前缀  生产环境
        //publicPath:'/'
        //chunkFilenname:'[name]_chunk.js',//非入口文件的名称
        //libray:'[name]'//整个库向外暴露
    },
    //loader配置
    module:{
        rules:[
            {   
                //test 匹配文件
                test:/\.css$/,
                //use数组 使用那些loader 从下往上执行
                use:[...commonCssLoader]
            },
            {
                test:/\.less$/,
                use:[
                    ...commonCssLoader,
                     //less-loader 将文件编译成css文件  需要下载less less-loader 
                     'less-loader',
                 ]
            },
            //处理图片资源
            {
                //处理不了html中的图片
                test:/\.(png|jpg|jpeg|gif)$/,
                loader:'url-loader',
                options:{
                    //图片大小限制 小于20kb 会被base64处理
                    //优点：减少请求数量
                    //缺点：图片体积更大
                    limit:6*1024,
                    //url-loader默认使用es6模块化解析,html-loader引入图片是commonjs
                    //解析时会出现问题[object Module]
                    //解决关闭url-loader的es6模块化使用commonjs解析
                    esModule:false,
                    publicPath:'../images/',//文件路径
                    outputPath:'images/',//指定输出路径
                    name:'[name][hash:10].[ext]'//默认名字保留前10位[hash:10].[ext]
                }
            },
            {
                //处理html中img图片
                test:/\.html$/,
                loader:'html-loader',
                options:{
                    esModule:false,//这个一定要加上不然html中打包图片生成路径会有问题
                } 
            },
            {
                //处理字体图标
                exclude:/\.(js|json|html|css|less|scss|png|gif|jpg|jpeg)$/,//其他资源
                 loader:'file-loader',
                 options:{
                     publicPath:'./font/',//文件路径
                     outputPath:'font/',//指定输出路径
                     name:'[name].[ext]',
                 }
           },
           {
            //eslint 只检查js语法
            /*
                设置检查规则
                package.json 中eslintConfig中设置
                "eslintConfig": {
                    "extends": "airbnb-base"
                }
            */
                test:/\.js$/,
                exclude:/node_modules/,//只检查自己写的，不检查第三发库的
                enforce:'pre',//优先执行    先执行 eslint 在执行babel
                loader:'eslint-loader',
                options:{
                    fix:true //修复语法错误
                }
            },
            //js兼容处理   项目尽量不要使用这个插件  会影响打包速度
            //{ test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ },//exclude排除项，不用转换这个文件夹的js

        ]
    },
    //插件配置
    plugins:[
        //创建一个空的html，引入打包所有资源
        new HtmlWebpackPlugin({
            //复制这个src下的html文件
            template:'./src/index.html',
            filename:'index.html',
            //压缩html代码
            minify:{
                //移除空格
                collapseWhitespace:true,
                //移除注释
                removeComments:true
            }
        }),
        //提取css为单独文件
        new MiniCssExtractPlugin({
            filename:'css/index.css'
        }),
        //压缩css代码
       new OptimizeCssAssetsWebpackPlugin(),
       //去掉无用代码
       new PurgecssWebpackPlugin({
        paths:glob.sync(`${PATHS.src}/**/*`,{nodir:true})
   })
    ],
    target:'web',//在webpack5之后版本需要加上这个配置项才能自动刷新
    mode:"development",  //development  开发环境       production 生产环境
    //target:'web',//在webpack5之后版本需要加上这个配置项才能自动刷新
    //devServer 自动化
    devServer:{
        //运行代码的目录
        contentBase:resolve(__dirname,'build'),
        //监视contentBase目录下所有文件，一旦文件变化就会reload
        //wacthContentBase:true,
        //端口号
        port:3001,
        //域名
        host:'localhost',
        //启动gzip压缩
        compress:true,
        //自动打开浏览器
        open:true,
        hot:true, //开启HRM
        //服务器代理 --->解决开发环境跨域问题
        // proxy:{
        //     //一旦devServer(3001)服务器接收到 /api/xxx的请求，就会把请求转发到另一个服务器(3000)
        //     '/api':{
        //         target:'http://localhost:3000',
        //         pathRewrite:{
        //             '^api':''
        //         }
        //     }
        // }
    },
    //devtool:'cheap-module-source-map',
    /*
      1.可以将node_modules中代码单独打包一个chunk最终输出
      2.自动分析多入口chunk中，有没有公共的文件，如果有会打包成单独一个chunk
    */
    optimization:{
        splitChunks:{
            chunks:'all',
        }
    },
     //解析模块的规则
     resolve:{
         //配置解析模块路径别名：简写路径
         alias:{
             $css:resolve(__dirname,'src/css')
         },
         //配置省略文件路径的后缀名
        extensions:['.js','.json'],
        //告诉webpack解析模块去哪个目录
        modules:[resolve(__dirname,'./node_modules'),'node_modules']
     }
}